package cate.game.activity.destinygate;

import cate.common.table.activity.destinygate.row.*;
import cate.common.table.d.GDFight;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDOperation;
import cate.common.table.d.GDPosition;
import cate.common.table.pay.PayItemRow;
import cate.common.util.GameResult;
import cate.game.activity.base.core.RoleFarmActivitySingle;
import cate.game.activity.destinygate.msg.DestinyGateDataResp;
import cate.game.activity.destinygate.po.DestinyGateChapter;
import cate.game.activity.destinygate.po.DestinyGateGift;
import cate.game.mail.po.MailBuilder;
import cate.game.play.fighter.HeroFighter;
import cate.game.play.part.FightSide;
import cate.game.play.part.PlaySide;
import cate.game.play.proce.play.PlayPO;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.role.Role;
import cate.game.role.mail.Mail;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

@NoteClass("命运之扉")
public class DestinyGateActivity extends RoleFarmActivitySingle {
    @NoteField(value = "英雄副本信息", detail = "map<英雄id，章节信息>")
    public Map<Integer, DestinyGateChapter> chapterMap;

    @NoteField(value = "完美通关英雄")
    public Set<Integer> fullPassIds;

    @NoteField(value = "（右侧2）自选英雄")
    public int cusHeroId;

    @NoteField(value = "(左侧1)自选英雄")
    public int sysHeroId;

    @JsonIgnore
    @NoteField(value = "挑战过的英雄副本信息", detail = "map<英雄id，章节信息>")
    public Map<Integer, DestinyGateChapter> challengedMap;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (chapterMap == null) {
            chapterMap = new HashMap<>();
        }
        if (challengedMap == null) {
            challengedMap = new HashMap<>();
        }
        if (fullPassIds == null) {
            fullPassIds = new HashSet<>();
        }
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {
        //活动结束发送未领取奖励
        sendDoneMail();
        if (cusHeroId != 0) {
            challengedMap.put(cusHeroId,chapterMap.get(cusHeroId));
        }
        if (sysHeroId != 0) {
            challengedMap.put(sysHeroId,chapterMap.get(sysHeroId));
        }
        cusHeroId = 0;
        sysHeroId = 0;
        chapterMap.clear();
    }

    /**
     * 活动结束未领取奖励邮件发送
     */
    private void sendDoneMail() {
        MixRes reward = new MixRes();
        for(DestinyGateChapter chapter : chapterMap.values()){
            //完美通关奖励
            DestinyGatePassRewardRow row = showChapterFullReward(chapter.heroId);
            if(chapter.pass && !chapter.fullPassGot){
                reward.addList(new MixRes(row.gift));
                chapter.fullPassGot = true;
            }
            //星级奖励
            Map<Integer, String> allStarMap = new HashMap<>();
            for (DestinyGateStarRewardRow starReward : role.getGame().table.destinyGate.starReward.getList()) {
                if (starReward.heroId == chapter.heroId && starReward.star <= chapter.star) {
                    allStarMap.put(starReward.id, starReward.gift);
                }
            }
            if (chapter.starRewardList != null && chapter.starRewardList.size() < allStarMap.size()) {
                for (int tid : allStarMap.keySet()) {
                    if (!chapter.starRewardList.contains(tid)) {
                        reward.addList(new MixRes(allStarMap.get(tid)));
                        chapter.starRewardList.add(tid);
                    }
                }
            }
        }
        if(!reward.isEmpty()){
            Mail mail = new MailBuilder()
                    .setReward(reward)
                    .setContentId(showBaseConfig().mailID)
                    .setOperation(GDOperation.DESTINY_GATE)
                    .setOperationSub(funcId())
                    .build();
            role.getGame().mail.send(role.getUid(), mail);
        }
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {
        DestinyGateBaseRow row = showBaseConfig();
        if (!enable() || row == null) {
            chapterMap.clear();
            return;
        }
        /*int sysHeroId = row.sysHeroId;
        List<Integer> ids = row.chooseHeroIds;
        ids.add(sysHeroId);
        chapterMap.entrySet().removeIf(kv -> !ids.contains(kv.getKey()));
        if (!chapterMap.containsKey(sysHeroId)) {
            DestinyGateChapter chapter = new DestinyGateChapter();
            chapter.initChapter(sysHeroId);
            List<DestinyGateGiftRow> gifts = showAllGifts(sysHeroId);
            for (DestinyGateGiftRow giftRow : gifts) {
                DestinyGateGift gift = new DestinyGateGift(giftRow.id, giftRow.heroId, false);
                chapter.giftMap.put(gift.tid, gift);
            }
            chapterMap.put(sysHeroId, chapter);
        }*/
        if (chapterMap.isEmpty()) {
            cusHeroId = 0;
            sysHeroId = 0;
        }
        if (!challengedMap.isEmpty()) {
            challengedMap.values().removeIf(Objects::isNull);
            challengedMap.values().forEach(
                    a -> {
                        if (a.star == 30 && a.pass && a.allBuy) {
                            fullPassIds.add(a.heroId);
                        }
                    });
        }
    }

    private DestinyGateBaseRow showBaseConfig() {
        DestinyGateBaseRow row = role.getGame().table.destinyGate.base.get(configTid());
        return row;
    }

    public DestinyGatePassRewardRow showChapterFullReward(int heroId) {
        DestinyGatePassRewardRow row = role.getGame().table.destinyGate.passReward.get(heroId);
        return row;
    }

    @Override
    public int getFightFuncId() {
        return GDFunc.DESTINY_GATE;
    }

    public void noticeUpdate(){
        if(enable()){
            role.sendNow(new DestinyGateDataResp(this));
        }
    }


    public synchronized DestinyGateChapter showChapter(int heroId) {
        DestinyGateChapter chapter = chapterMap.get(heroId);
        if (chapter == null) {
            chapter = new DestinyGateChapter();
            chapter.initChapter(heroId);
            if (heroId > 0) {
                chapterMap.put(heroId, chapter);
            }
        }
        return chapter;
    }

    /**
     * 自选英雄
     * @param heroId
     * @return
     */
    public GameResult<DestinyGateActivity> chooseHero(int heroId, int pos) {
        GameResult<DestinyGateActivity> r = new GameResult<>();
        DestinyGateBaseRow baseRow = showBaseConfig();
        if (baseRow == null) {
            return r.fail("活动配置不存在");
        }

        if (fullPassIds.contains(heroId)) {
            return r.fail("已完美达成该英雄命运之扉");
        }

        if (pos == 0) {
            pos = 1;
        }
        List<Integer> ids = new ArrayList<>();
        if (pos == 2) {
            ids = baseRow.chooseHeroIds;
        } else {
            ids = baseRow.sysHeroIds;
        }
        if (heroId == 0 || !ids.contains(heroId)) {
            return r.fail("选择了不存在的英雄");
        }
        if (pos == 1 && heroId == cusHeroId) {
            return r.fail("不可重复选择相同英雄");
        } else if (pos == 2 && heroId == sysHeroId){
            return r.fail("不可重复选择相同英雄");
        }
        if (pos == 2) {
            cusHeroId = heroId;
        } else {
            sysHeroId = heroId;
        }

        DestinyGateChapter chapter = null;
        if (!challengedMap.isEmpty()) {
            chapter = challengedMap.get(heroId);
        }

        if (chapter == null) {
            chapter = new DestinyGateChapter();
            chapter.initChapter(heroId);
            List<DestinyGateGiftRow> gifts = showAllGifts(heroId);
            for (DestinyGateGiftRow giftRow : gifts) {
                DestinyGateGift gift = new DestinyGateGift(giftRow.id, giftRow.heroId, false);
                chapter.giftMap.put(gift.tid, gift);
            }
        }
        chapterMap.put(heroId, chapter);
        noticeUpdate();
        return r;
    }

    /**
     * 领取完美通关奖励
     * @param heroId
     * @return
     */
    public GameResult<DestinyGateActivity> provideChapterReward(int heroId) {
        GameResult<DestinyGateActivity> r = new GameResult<>();
        DestinyGateChapter chapter = chapterMap.get(heroId);
        if (chapter == null) {
            return r.fail("所选英雄副本不存在");
        }
        if (!chapter.pass) {
            return r.fail("完成该副本全部成就挑战后领取");
        }
        DestinyGatePassRewardRow row = showChapterFullReward(heroId);
        if (row == null || StringUtils.isBlank(row.gift)){
            return r.fail("所选英雄完美挑战奖励不存在");
        }
        r = chapter.provideChapterReward(row, role);
        noticeUpdate();
        return r;
    }

    /**
     * 领取星数奖励
     * @param tid
     * @return
     */
    public GameResult<DestinyGateActivity> provideStarReward(int tid) {
        GameResult<DestinyGateActivity> r = new GameResult<>();
        DestinyGateStarRewardRow row = showStarReward(tid);
        if (row == null || StringUtils.isBlank(row.gift)) {
            return r.fail("奖励配置不存在");
        }
        DestinyGateChapter chapter = chapterMap.get(row.heroId);
        if (chapter == null) {
            return r.fail("所选英雄副本不存在");
        }
        r = chapter.provideStarReward(tid, row, role);
        noticeUpdate();
        return r;
    }

    private DestinyGateStarRewardRow showStarReward(int tid) {
        DestinyGateStarRewardRow row = role.getGame().table.destinyGate.starReward.get(tid);
        return row;
    }

    private DestinyGateChapterRow showChapterRow(int tid) {
        DestinyGateChapterRow row = role.getGame().table.destinyGate.chapter.get(tid);
        return row;
    }

    public List<DestinyGateGiftRow> showAllGifts(int heroId) {
        List<DestinyGateGiftRow> row = role.getGame().table.destinyGate.gift.showGifts(heroId);
        return row;
    }

    public DestinyGateGiftRow showGift(int tid) {
        DestinyGateGiftRow row = role.getGame().table.destinyGate.gift.get(tid);
        return row;
    }

    /**
     * 挑战
     * @param combatNum
     * @return
     */
    public GameResult<DestinyGateActivity> challenge(int combatNum) {
        GameResult<DestinyGateActivity> r = new GameResult<>();
        if (fighting) {
            return r.fail("当前正在战斗中");
        }
        DestinyGateChapterRow row = showChapterRow(combatNum);
        if (row == null) {
            return r.fail("挑战关卡不存在");
        }
        DestinyGateChapter chapter = chapterMap.get(row.heroId);
        if (chapter == null) {
            return r.fail("所选英雄副本不存在");
        }
        if (row.levelBefore > 0) {
            DestinyGateChapterRow rowBefore = showBeforeRow(row.levelBefore, row.heroId);
            if (rowBefore != null && !chapter.levelMap.containsKey(rowBefore.id)) {
                return r.fail("请先挑战前置关卡");
            }
        }
        r = doChallenge(combatNum, row);
        return r;
    }

    private DestinyGateChapterRow showBeforeRow(int levelBefore, int heroId) {
        return role.getGame().table.destinyGate.chapter.showBeforeRow(levelBefore, heroId);
    }

    private List<DestinyGateGiftConditionRow> showConditionRow(int giftId) {
        return role.getGame().table.destinyGate.giftCondition.showConditionRow(giftId);
    }

    private GameResult<DestinyGateActivity> doChallenge(int combatNum, DestinyGateChapterRow row) {
        GameResult<DestinyGateActivity> r = new GameResult<>();
        EcResult<FightSide> fsResult = role.getGame().fight.side.createFightSideByCode(GDFight.Team.B, row.dynInsCode);
        if (!fsResult.ok()) {
            return r.fail(fsResult.message);
        }
        //己方阵容
        EcResult<FightSide> psA_r = role.getGame().fight.side.createFightSideByRole(GDFight.Team.A, role, getFightFuncId());
        FightSide fightSideA = psA_r.data;
        String challengeConf = row.challengeConf;
        List<Integer> needStar = new ArrayList<>();
        //上阵人数
        if (fightSideA.ft.getAllHero().size() > row.max) {
            return r.fail("不满足上阵人数");
        }
        //挑战英雄星级
        if (org.apache.commons.lang3.StringUtils.isNotBlank(challengeConf)) {
            String[] split = challengeConf.split(":");
            for (String str : split) {
                needStar.add(Integer.parseInt(str));
            }
            HeroFighter heroFighter = fightSideA.ft.findHeroByProtoId(needStar.get(0));
            if (heroFighter == null || heroFighter.star < needStar.get(1)){
                return r.fail("不满足挑战需求星级");
            }
        }
        DestinyGateFTC context = new DestinyGateFTC(role, row, getFightFuncId());
        context.funcId = getFightFuncId();
        context.playStory.level = combatNum;
        EcResult<PlayPO> fightRes =  role.getGame().play.startByRole(role, context, fsResult.data);
        if (!fightRes.ok()) {
            return r.fail(fightRes.message);
        }
        this.startFighting();
        return r;
    }

    /**
     * 支付条件
     * @param pir 支付配置
     * @return
     */
    @Override
    public GameResult<Void> allowPay(PayItemRow pir) {
        GameResult<Void> r = new GameResult<>();
        int tid = pir.funcSubId;
        DestinyGateGiftRow giftRow = showGift(tid);
        if (giftRow == null) {
            return r.fail("礼包配置不存在");
        }
        DestinyGateChapter chapter = chapterMap.get(giftRow.heroId);
        if (chapter == null) {
            return r.fail("所选英雄副本不存在");
        }
        if (!chapter.giftMap.containsKey(tid)) {
            return r.fail("礼包不存在");
        }
        if (chapter.giftMap != null && chapter.giftMap.get(tid).buy) {
            return r.fail("已达礼包购买次数上限");
        }
        List<DestinyGateGiftConditionRow> conditions = showConditionRow(giftRow.id);
        r = chapter.checkCondition(giftRow.limit, chapter.giftMap.get(tid).buyTime, conditions);
        if (!r.ok()){
            return r;
        }
        MixRes rewardRes = new MixRes(giftRow.gift);
        if (rewardRes.isEmpty()) {
            return r.fail("奖励为空");
        }
        return r.success();
    }

    @Override
    public void onPaySuccess(PayItemRow payItemRow) {
        provideReward(role, payItemRow.funcSubId, true);
    }

    /**
     * 购买后发放奖励
     * @param role
     * @param tid
     * @param dialog
     */
    protected void provideReward(Role role, int tid, boolean dialog) {
        DestinyGateGiftRow giftRow = showGift(tid);
        if (giftRow == null) {
            return ;
        }
        MixRes rewardRes = new MixRes(giftRow.gift);
        if (rewardRes.isEmpty()) {
            return ;
        }
        DestinyGateChapter chapter = chapterMap.get(giftRow.heroId);
        EcResult<?> exe = new MixResAdder().setRes(rewardRes)
                .setOperation(GDOperation.DESTINY_GATE)
                .setOperationSub(tid)
                .setDialogReward(dialog)
                .setSendMailWhenFull(true)
                .exe(role);
        chapter.giftMap.get(tid).buyTime ++;
        if (chapter.giftMap.get(tid).buyTime == (giftRow.limit + giftRow.extraTimes)) {
            chapter.giftMap.get(tid).buy = true;
            boolean allBuy = true;
            for (DestinyGateGift gift : chapter.giftMap.values()) {
                if (gift.buy == false) {
                    allBuy = false;
                }
            }
            chapter.allBuy = allBuy;
        }
        noticeUpdate();
    }

}
